﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EmailEventLog
{
    using System.Threading;
    using System.Globalization;
    using System.Diagnostics.Eventing;
    using System.Diagnostics.Eventing.Reader;
    using System.Net.Mail;
    using System.IO;

    class Program
    {
        public static int SecondsHistory()
        {
            return int.Parse(System.Configuration.ConfigurationManager.AppSettings["SecondsHistoryInterval"]);
        }

        public static int SecondsToRun()
        {
            return int.Parse(System.Configuration.ConfigurationManager.AppSettings["SecondsInterval"]);
        }

        private static TimeSpan time = TimeSpan.FromSeconds(SecondsToRun());
        private static TimeSpan history = TimeSpan.FromSeconds(SecondsHistory());

        private static DirectoryInfo di = new DirectoryInfo("Filters");
        private static List<string> allClearMessages = new List<string>();

        static void Main(string[] args)
        {
            Loop();
        }

        private static IEnumerable<DirectoryInfo> GetDirectories()
        {
            return di.GetDirectories();
        }

        private static IEnumerable<FileInfo> GetFiles(DirectoryInfo di)
        {
            return di.GetFiles();
        }

        private static string ParseFile(FileInfo fi)
        {
            var fc = File.ReadAllText(fi.FullName);
            fc = fc.Replace("##TimeRange##", ((long)history.TotalMilliseconds).ToString());
            return fc;

        }

        private static void Loop()
        {
            while (true)
            {
                try
                {
                    LookThroughFolders();

                }
                catch (Exception ex)
                {
                    Email("Error on Loop", ex);
                }
                finally
                {
                    System.Threading.Thread.Sleep(time);
                }
            }
        }

        static void LookThroughFolders()
        {
            foreach (var d in GetDirectories())
            {

                foreach (var f in GetFiles(d))
                {
                    try
                    {
                        var fc = ParseFile(f);
                        DoWork(fc, d.Name, f.Name);
                    }
                    catch (Exception ex)
                    {
                        Email("Error Reading Event Logs", ex);
                    }
                }
            }

            SendAllClearMessages();
        }

        static void DoWork(string filter, string logName, string fileName)
        {

            var q = new EventLogQuery(logName, PathType.LogName, filter);
            var elReader = new EventLogReader(q);

            List<EventRecord> eventList = new List<EventRecord>();
            for (EventRecord eventInstance = elReader.ReadEvent(); null != eventInstance; eventInstance = elReader.ReadEvent())
            {
                eventList.Add(eventInstance);
            }

            var beforeCulture = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

            foreach (var x in eventList)
            {
                try
                {
                    Email(x);
                }
                finally
                {
                }
            }

            if (eventList.Count == 0)
            {
                AddToAllClear(logName, fileName);
            }
        }

        static IEnumerable<string> GetToAddresses()
        {
            var tos = System.Configuration.ConfigurationManager.AppSettings["ToAddresses"];
            return tos.Split(";".ToCharArray());
        }

        static void AddToAllClear(string system, string fileName)
        {
            allClearMessages.Add(string.Format("Event Log All clear reading {0} file {1}", system, fileName));

        }

        static void SendAllClearMessages()
        {
            if (allClearMessages.Count == 1)
            {
                Email(allClearMessages.First(), string.Empty, MailPriority.Low);
            }
            else if(allClearMessages.Count>1)
            {
                var sb = new StringBuilder();
                foreach (var x in allClearMessages)
                {
                    sb.AppendLine(x);
                }
                Email("Event Log All clear", sb.ToString(), MailPriority.Low);
                allClearMessages.Clear();
            }
        }

        static void Email(EventRecord record)
        {
            var body = record.FormatDescription();
            body = body + "<br>" + "<br>";
            body = body + record.ToXml();
            var c = new SmtpClient();

            var m = new MailMessage();

            var adds = GetToAddresses();
            foreach (var add in adds)
            {
                m.To.Add(new MailAddress(add));
            }

            var priority = (record.Level <= 2) ? MailPriority.High : MailPriority.Normal;

            var subject = "Event Log " + record.MachineName + " " + record.LevelDisplayName + " " + record.Id + " " + record.TimeCreated;

            Email(subject, body, priority);
        }

        static void Email(string subject, Exception ex)
        {
            try
            {
                Email(subject, ex.Message.ToString() + Environment.NewLine + ex.StackTrace.ToString(), MailPriority.High);
            }
            finally
            {

            }
        }

        static void Email(string subject, string message, MailPriority priority)
        {
            var c = new SmtpClient();
            var m = new MailMessage();

            var adds = GetToAddresses();
            foreach (var add in adds)
            {
                m.To.Add(new MailAddress(add));
            }

            m.Priority = priority;
            m.Subject = subject;
            m.Body = message;
            m.IsBodyHtml = true;

            Write(subject, message);
            c.Send(m);
        }

        static void Write(string subject, string message)
        {
            var sb = new StringBuilder();
            sb.AppendLine(DateTime.Now.ToString());
            sb.AppendLine(subject);
            sb.AppendLine(message);
            sb.AppendLine();
            sb.AppendLine();

            Console.WriteLine(sb.ToString());
        }
    }
}
